package org.dhbw.cocktail.mixer.internal;

import java.util.List;

import lombok.Data;

import org.dhbw.cocktail.Cocktail;
import org.dhbw.cocktail.CocktailType;
import org.dhbw.cocktail.Ingredient;
import org.dhbw.cocktail.UsedIngredient;
import org.dhbw.cocktail.mixer.ICocktailMixer;
import org.springframework.transaction.annotation.Transactional;

/**
 * Implementation of the ICocktailMixer Interface
 * 
 * @author Roland von Werden
 * @version 0.1.1
 */
@Data
public class PersistentCocktailMixer implements ICocktailMixer {

	private CocktailDAO dao;

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<Cocktail> getAllCocktails() {
		return dao.getCocktails();
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<Cocktail> searchCocktail(String searchString) {
		return dao.searchCocktail(searchString);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	@Transactional
	public boolean saveCocktail(Cocktail cocktail) {
		return dao.saveCocktail(cocktail);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	@Transactional
	public boolean saveIngredient(String name, double quantity, String unit) {
		Ingredient ingr = new Ingredient();
		ingr.setName(name);
		ingr.setAmount(quantity);
		ingr.setUnit(unit);
		return this.saveIngredient(ingr);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	@Transactional
	public boolean saveIngredient(Ingredient ingredient) {
		return dao.saveIngredient(ingredient);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	@Transactional
	public boolean mixCocktail(Cocktail cocktail, int quantity) {

		cocktail = dao.getCocktailById(cocktail.getId());
		List<UsedIngredient> usedIngredients = cocktail.getIngredientsUsed();
		// Test if there are enough Ingredients for the amount of cocktails to
		// mix
		boolean hasEnoghAmount = true;
		for (UsedIngredient usedIngredient : usedIngredients) {
			double neededAmount = usedIngredient.getNeededAmount() * quantity;
			// Check if there's enough Amount left
			if (usedIngredient.getIngredient().getAmount() - neededAmount < 0) {
				// if one Ingredient fails the test, the cocktail(s) cannot be
				// mixed
				hasEnoghAmount = false;
			}
		}
		// "mix" cocktail
		if (hasEnoghAmount) {
			for (UsedIngredient usedIngredient : usedIngredients) {
				double neededQuantity = usedIngredient.getNeededAmount()
						* quantity;
				// Remove the needed amount from the ingredients
				usedIngredient.getIngredient().removeAmount(neededQuantity);
				
			}
			dao.saveCocktail(cocktail);
			return true;
		}
		return false;
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<Ingredient> getIngredients() {
		return dao.getIngredients();
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<CocktailType> getCocktailTypes() {
		return dao.getCocktailTypes();
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public boolean saveCocktailType(CocktailType type) {
		return dao.saveCocktailType(type);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public Cocktail getCocktailById(long id) {
		return dao.getCocktailById(id);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	@Transactional
	public Ingredient getIngredientById(long id) {
		Ingredient res = dao.getIngredientById(id);
		//res.setAmount(res.getAmount()-1);
		return res;
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public CocktailType getCocktailTypeById(long id) {
		return dao.getCocktailTypeById(id);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<Ingredient> searchIngredient(String searchString) {
		return dao.searchIngredient(searchString);
	}

	/**
	 * @see ICocktailMixer
	 */
	@Override
	public List<Cocktail> getCocktailsByIngredientId(long id) {
		return dao.getCocktailsByIngredientId(id);
	}

}
